package org.rsbot.util;

import java.awt.Image;
import java.awt.Toolkit;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Properties;
import java.util.logging.FileHandler;
import java.util.logging.LogManager;

import javax.swing.JOptionPane;
import javax.swing.filechooser.FileSystemView;

import org.rsbot.log.LogFormatter;
import org.rsbot.log.SystemConsoleHandler;
import org.rsbot.log.TextAreaLogHandler;

public class GlobalConfiguration {

	public enum OperatingSystem {
		MAC, WINDOWS, LINUX, UNKNOWN
	}

	public static class Paths {
		public static class Resources {
			public static final String ROOT = "resources";
			public static final String SCRIPTS = Paths.SCRIPTS_NAME_SRC + "/";

			public static final String ROOT_IMG = "/" + Resources.ROOT + "/images";
			public static final String ICON = Resources.ROOT_IMG + "/icon.png";
			public static final String ICON_DELETE = Resources.ROOT_IMG + "/delete.png";
			public static final String ICON_PLAY = Resources.ROOT_IMG + "/control_play_blue.png";
			public static final String ICON_PAUSE = Resources.ROOT_IMG + "/control_pause.png";
			public static final String ICON_ADD = Resources.ROOT_IMG + "/add.png";
			public static final String ICON_ADD_OVER = Resources.ROOT_IMG + "/add_over.png";
			public static final String ICON_ADD_DOWN = Resources.ROOT_IMG + "/add_down.png";
			public static final String ICON_HOME = Resources.ROOT_IMG + "/home.png";
			public static final String ICON_BOT = Resources.ROOT_IMG + "/bot.png";
			public static final String ICON_CLOSE = Resources.ROOT_IMG + "/close.png";
			public static final String ICON_CLOSE_OVER = Resources.ROOT_IMG + "/close_over.png";
			public static final String ICON_TICK = Resources.ROOT_IMG + "/tick.png";
			public static final String ICON_MOUSE = Resources.ROOT_IMG + "/mouse.png";
			public static final String ICON_KEYBOARD = Resources.ROOT_IMG + "/keyboard.png";
			public static final String ICON_CONNECT = Resources.ROOT_IMG + "/connect.png";
			public static final String ICON_DISCONNECT = Resources.ROOT_IMG + "/disconnect.png";
			public static final String ICON_START = Resources.ROOT_IMG + "/control_play.png";
			public static final String ICON_SCRIPT_BDL = Resources.ROOT_IMG + "/script_bdl.png";
			public static final String ICON_SCRIPT_DRM = Resources.ROOT_IMG + "/script_drm.png";
			public static final String ICON_SCRIPT_PRE = Resources.ROOT_IMG + "/script_pre.png";
			public static final String ICON_SCRIPT_SRC = Resources.ROOT_IMG + "/script_src.png";
			public static final String UPARROW = Resources.ROOT_IMG + "/arrow_up.png";            
			public static final String DOWNARROW = Resources.ROOT_IMG + "/arrow_down.png";
			public static final String CPU = Resources.ROOT_IMG + "/cpu.png";
                        public static final String BUG = Resources.ROOT_IMG + "/bug.png";
                        public static final String ACCOUNT = Resources.ROOT_IMG + "/account.png";
                        public static final String ABOUT = Resources.ROOT_IMG + "/about.png";
                        public static final String HOME_ICON = Resources.ROOT_IMG + "/home-icon.png";
                        public static final String LOG = Resources.ROOT_IMG + "/log.png";
                        public static final String CONSOLE = Resources.ROOT_IMG + "/console.png";
                        public static final String SPLASH = Resources.ROOT_IMG + "/splash.png";
                        public static final String SCRIPT_EDIT = Resources.ROOT_IMG + "/script_edit.png";
                        public static final String PENCIL = Resources.ROOT_IMG + "/pencil.png";
                        public static final String GUI_BUTTON = Resources.ROOT_IMG + "/gui_button.png";
                        public static final String GUI_CLOSE = Resources.ROOT_IMG + "/gui_close.png";
                        public static final String HELP = Resources.ROOT_IMG + "/help.png";
                        public static final String SHOT_DO = Resources.ROOT_IMG + "/shot_do.png";
                        public static final String SHOT_UN_DO = Resources.ROOT_IMG + "/shotun_do.png";
                        public static final String STOP_DO = Resources.ROOT_IMG + "/stop.png";
                        public static final String TOOLS_HIDE = Resources.ROOT_IMG + "/tools_gui.png";
                        public static final String BOTTOM_HIDE = Resources.ROOT_IMG + "/bottom_gui.png";
                        public static final String TRAY_HIDE = Resources.ROOT_IMG + "/tray_icon.png";
                        public static final String WEB_SMALL = Resources.ROOT_IMG + "/web_small.png";
                        public static final String WIKI = Resources.ROOT_IMG + "/wiki.png";
                        public static final String FACE = Resources.ROOT_IMG + "/face.png";
                        public static final String TWIT = Resources.ROOT_IMG + "/twit.png";
                        public static final String CUT = Resources.ROOT_IMG + "/cut.png";
                        public static final String COPY = Resources.ROOT_IMG + "/copy.png";
                        public static final String PASTE = Resources.ROOT_IMG + "/paste.png";
                        public static final String SAVE = Resources.ROOT_IMG + "/save.png";
                        public static final String ENF = Resources.ROOT_IMG + "/enfinity.png";
                        public static final String IRC = Resources.ROOT_IMG + "/irc.png";
                        public static final String REWARD = Resources.ROOT_IMG + "/reward.png";
                        public static final String DELAY = Resources.ROOT_IMG + "/delay.png";
                        public static final String OPTION = Resources.ROOT_IMG + "/option.png";
                        public static final String DEV = Resources.ROOT_IMG + "/dev.png";

			public static final String VERSION = Resources.ROOT + "/version.dat";
                        public static final String ITEMID = Resources.ROOT + "/ItemID.dat";
                        public static final String NPCID = Resources.ROOT + "/NPCID.dat";
		}

		public static class URLs {
                        public static final String SVNDAT = "http://wyeupijgdijpzgfi.googlecode.com/svn/trunk/";
                        public static final String UPDATER = "http://infinity-client.googlecode.com/svn/trunk/";
                        public static final String DOWNLOAD = SVNDAT + "Uglyness";
                        public static final String UPDATE = SVNDAT + "mod";
                        public static final String VERSION = SVNDAT + "version.dat";
                        public static final String PROJECT = "http://code.google.com/p/infinity-client/";
                        public static final String SITE = "http://www.runedev-infinity.org/";
		}

		public static final String ROOT = "." + File.separator + "resources";

		public static final String COMPILE_SCRIPTS_BAT = "Compile-Scripts.bat";
		public static final String COMPILE_SCRIPTS_SH = "compile-scripts.sh";
		public static final String COMPILE_FIND_JDK = "FindJDK.bat";

		public static final String ROOT_IMG = Paths.ROOT + File.separator + "images";
		public static final String ICON = Paths.ROOT_IMG + File.separator + "icon.png";
		public static final String ICON_DELETE = Paths.ROOT_IMG + File.separator + "delete.png";
		public static final String ICON_PLAY = Paths.ROOT_IMG + File.separator + "control_play_blue.png";
		public static final String ICON_PAUSE = Paths.ROOT_IMG + File.separator + "control_pause.png";
		public static final String ICON_ADD = Paths.ROOT_IMG + File.separator + "add.png";
		public static final String ICON_ADD_OVER = Paths.ROOT_IMG + File.separator + "add_over.png";
		public static final String ICON_ADD_DOWN = Paths.ROOT_IMG + File.separator + "add_down.png";
		public static final String ICON_HOME = Paths.ROOT_IMG + File.separator + "home.png";
		public static final String ICON_BOT = Paths.ROOT_IMG + File.separator + "bot.png";
		public static final String ICON_CLOSE = Paths.ROOT_IMG + File.separator + "close.png";
		public static final String ICON_CLOSE_OVER = Paths.ROOT_IMG + File.separator + "close_over.png";
		public static final String ICON_TICK = Paths.ROOT_IMG + File.separator + "tick.png";
		public static final String ICON_MOUSE = Paths.ROOT_IMG + File.separator + "mouse.png";
		public static final String ICON_KEYBOARD = Paths.ROOT_IMG + File.separator + "keyboard.png";
		public static final String ICON_CONNECT = Paths.ROOT_IMG + File.separator + "connect.png";
		public static final String ICON_DISCONNECT = Paths.ROOT_IMG + File.separator + "disconnect.png";
		public static final String ICON_START = Paths.ROOT_IMG + File.separator + "control_play.png";
		public static final String ICON_SCRIPT_BDL = Paths.ROOT_IMG + File.separator + "script_bdl.png";
		public static final String ICON_SCRIPT_DRM = Paths.ROOT_IMG + File.separator + "script_drm.png";
		public static final String ICON_SCRIPT_PRE = Paths.ROOT_IMG + File.separator + "script_pre.png";
		public static final String ICON_SCRIPT_SRC = Paths.ROOT_IMG + File.separator + "script_src.png";

		
		public static final String UPARROW = Paths.ROOT_IMG + File.separator + "arrow_up.png";
        public static final String DOWNARROW = Paths.ROOT_IMG + File.separator + "arrow_down.png";
                
		
		public static final String BUG = Paths.ROOT_IMG + File.separator + "bug.png";
                public static final String ACCOUNT = Paths.ROOT_IMG + File.separator + "account.png";
                public static final String ABOUT = Paths.ROOT_IMG + File.separator + "about.png";
                public static final String CPU = Paths.ROOT_IMG + File.separator + "cpu.png";
                public static final String HOME_ICON = Paths.ROOT_IMG + File.separator + "home-icon.png";
                public static final String LOG = Paths.ROOT_IMG + File.separator + "log.png";
                public static final String CONSOLE = Paths.ROOT_IMG + File.separator + "console.png";
                public static final String SPLASH = Paths.ROOT_IMG + File.separator + "splash.png";
                public static final String SCRIPT_EDIT = Paths.ROOT_IMG + "/script_edit.png";
                public static final String PENCIL = Paths.ROOT_IMG + "/pencil.png";
                public static final String GUI = Paths.ROOT_IMG + "/gui.png";
                public static final String GUI_BUTTON = Paths.ROOT_IMG + "/gui_button.png";
                public static final String GUI_CLOSE = Paths.ROOT_IMG + "/gui_close.png";
                public static final String HELP = Paths.ROOT_IMG + "/help.png";
                public static final String ICON_STOP = Paths.ROOT_IMG + File.separator + "stop.png";
                public static final String SHOT_DO = Paths.ROOT_IMG + File.separator + "shot_do.png";
                public static final String SHOT_UN_DO = Paths.ROOT_IMG + File.separator + "shotun_do.png";
                public static final String STOP_DO = Paths.ROOT_IMG + File.separator + "stop.png";
                public static final String TOOLS_HIDE = Paths.ROOT_IMG + File.separator + "tools_gui.png";
                public static final String BOTTOM_HIDE = Paths.ROOT_IMG + File.separator + "bottom_gui.png";
                public static final String TRAY_HIDE = Paths.ROOT_IMG + File.separator + "tray_icon.png";
                public static final String WEB_SMALL = Paths.ROOT_IMG + File.separator + "web_small.png";
                public static final String WIKI = Paths.ROOT_IMG + File.separator + "wiki.png";
                public static final String FACE = Paths.ROOT_IMG + File.separator + "face.png";
                public static final String TWIT = Paths.ROOT_IMG + File.separator + "twit.png";
                public static final String CUT = Paths.ROOT_IMG + File.separator + "cut.png";
                public static final String COPY = Paths.ROOT_IMG + File.separator + "copy.png";
                public static final String PASTE = Paths.ROOT_IMG + File.separator + "paste.png";
                public static final String SAVE = Paths.ROOT_IMG + File.separator + "save.png";
                public static final String ENF = Paths.ROOT_IMG + File.separator + "enfinity.png";
                public static final String IRC = Paths.ROOT_IMG + File.separator + "irc.png";
                public static final String REWARD = Paths.ROOT_IMG + File.separator + "irc.png";
                public static final String DELAY = Paths.ROOT_IMG + File.separator + "delay.png";
                public static final String OPTION = Paths.ROOT_IMG + File.separator + "option.png";
                public static final String DEV = Paths.ROOT_IMG + File.separator + "dev.png";

		public static final String VERSION = Paths.ROOT + File.separator + "version.dat";
                public static final String ITEMID = Paths.ROOT + File.separator + "ItemID.dat";
                public static final String NPCID = Paths.ROOT + File.separator + "NPCID.dat";

		public static final String SCRIPTS_NAME_SRC = "scripts";
		public static final String SCRIPTS_NAME_OUT = "Scripts";

		public static String getAccountsFile() {
			return Paths.getSettingsDirectory() + File.separator + "acts";
		}

		public static String getHomeDirectory() {
			final String env = System.getenv(GlobalConfiguration.NAME.toUpperCase() + "_HOME");
			if ((env == null) || env.isEmpty())
				return (GlobalConfiguration.getCurrentOperatingSystem() == OperatingSystem.WINDOWS ? FileSystemView.getFileSystemView().getDefaultDirectory().getAbsolutePath() : Paths.getUnixHome()) + File.separator + GlobalConfiguration.NAME;
			else
				return env;
		}

		public static String getLogsDirectory() {
			return Paths.getHomeDirectory() + File.separator + "Logs";
		}

		public static String getMenuCache() {
			return Paths.getSettingsDirectory() + File.separator + "Menu.txt";
		}

		public static String getPathCache() {
			return Paths.getSettingsDirectory() + File.separator + "path.txt";
		}

		public static String getBootCache() {
			return Paths.getSettingsDirectory() + File.separator + "boot.txt";
		}

                public static String getUIDsFile() {
			return Paths.getSettingsDirectory() + File.separator + "uid.txt";
		}

		public static String getScreenshotsDirectory() {
			return Paths.getHomeDirectory() + File.separator + "Screenshots";
		}

		public static String getScriptsDirectory() {
			return Paths.getHomeDirectory() + File.separator + Paths.SCRIPTS_NAME_OUT;
		}

		public static String getScriptsPrecompiledDirectory() {
			return Paths.getScriptsDirectory() + File.separator + "Precompiled";
		}

		public static String getCacheDirectory() {
			return Paths.getHomeDirectory() + File.separator + "Cache";
		}

		public static String getVersionCache() {
			return Paths.getCacheDirectory() + File.separator + "info.dat";
		}

		public static String getModScriptCache() {
			return Paths.getCacheDirectory() + File.separator + "ms.dat";
		}

		public static String getClientCache() {
			return Paths.getCacheDirectory() + File.separator + "client.dat";
		}

		public static String getSettingsDirectory() {
			return Paths.getHomeDirectory() + File.separator + "Settings";
		}

                public static String getBreaksDirectory() {
                        return Paths.getSettingsDirectory() + File.separator + "Breaks.txt";
                }

		public static String getUnixHome() {
			final String home = System.getProperty("user.home");
			return home == null ? "~" : home;
		}
	}

	public static final String NAME = "Infinity";

	public static final String NAME_LOWERCASE = NAME.toLowerCase();

	public static final String SITE_NAME = "Lazygamerz";

	private static final OperatingSystem CURRENT_OS;

	public static boolean RUNNING_FROM_JAR = false;

	static {
		final URL resource = GlobalConfiguration.class.getClassLoader().getResource(Paths.Resources.VERSION);
		if (resource != null) {
			GlobalConfiguration.RUNNING_FROM_JAR = true;
			
		}
		/*
		String className = GlobalConfiguration.class.getName().replace('.', '/');
		String classJar = GlobalConfiguration.class.getResource(
				"/resources/version.dat").toString();
		if (classJar.startsWith("jar:")) {
			GlobalConfiguration.RUNNING_FROM_JAR = true;
		}
		
		System.out.println("runningfromjar " + GlobalConfiguration.RUNNING_FROM_JAR + " " + classJar);
		*/

		final String os = System.getProperty("os.name");
		if (os.contains("Mac")) {
			CURRENT_OS = OperatingSystem.MAC;
		} else if (os.contains("Windows")) {
			CURRENT_OS = OperatingSystem.WINDOWS;
		} else if (os.contains("Linux")) {
			CURRENT_OS = OperatingSystem.LINUX;
		} else {
			CURRENT_OS = OperatingSystem.UNKNOWN;
		}

		final ArrayList<String> dirs = new ArrayList<String>();
		dirs.add(Paths.getHomeDirectory());
		dirs.add(Paths.getLogsDirectory());
		dirs.add(Paths.getCacheDirectory());
		dirs.add(Paths.getSettingsDirectory());
		if (GlobalConfiguration.RUNNING_FROM_JAR) {
			dirs.add(Paths.getScriptsDirectory());
			dirs.add(Paths.getScriptsPrecompiledDirectory());
		}

		for (final String name : dirs) {
			final File dir = new File(name);
			if (!dir.exists()) {
				dir.mkdirs();
			}
		}

		Properties logging = new Properties();
		String logFormatter = LogFormatter.class.getCanonicalName();
		String fileHandler = FileHandler.class.getCanonicalName();
		logging.setProperty("handlers", TextAreaLogHandler.class.getCanonicalName() + "," + fileHandler);
		logging.setProperty(".level", "INFO");
		logging.setProperty(SystemConsoleHandler.class.getCanonicalName() + ".formatter", logFormatter);
		logging.setProperty(fileHandler + ".formatter", logFormatter);
		logging.setProperty(TextAreaLogHandler.class.getCanonicalName() + ".formatter", logFormatter);
		logging.setProperty(fileHandler + ".pattern", Paths.getLogsDirectory() + File.separator + "%u.%g.log");
		logging.setProperty(fileHandler + ".count", "10");
		final ByteArrayOutputStream logout = new ByteArrayOutputStream();
		try {
			logging.store(logout, "");
			LogManager.getLogManager().readConfiguration(new ByteArrayInputStream(logout.toByteArray()));
		} catch (final Exception ignored) {
		}

		if (GlobalConfiguration.RUNNING_FROM_JAR) {
			String path = resource.toString();
			try {
				path = URLDecoder.decode(path, "UTF-8");
			} catch (final UnsupportedEncodingException ignored) {
			}
			final String prefix = "jar:file:/";
			if (path.indexOf(prefix) == 0) {
				path = path.substring(prefix.length());
				path = path.substring(0, path.indexOf('!'));
				if (File.separatorChar != '/') {
					path = path.replace('/', File.separatorChar);
				}
				try {
					final File pathfile = new File(Paths.getPathCache());
					if (pathfile.exists()) {
						pathfile.delete();
					}
					pathfile.createNewFile();
					Writer out = new BufferedWriter(new FileWriter(Paths.getPathCache()));
					out.write(path);
					out.close();
				} catch (final Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	public static Image getImage(String resource, String path) {
		try {
			return Toolkit.getDefaultToolkit().getImage(GlobalConfiguration.RUNNING_FROM_JAR ?
					GlobalConfiguration.class.getResource(resource) : new File(path).toURI().toURL());
		} catch (Exception ignored) {
		}
		return null;
	}

	public static OperatingSystem getCurrentOperatingSystem() {
		return GlobalConfiguration.CURRENT_OS;
	}

	public static String getHttpUserAgent() {
		String plat = "Windows", os = "Windows NT 5.2";
		if (GlobalConfiguration.getCurrentOperatingSystem() == GlobalConfiguration.OperatingSystem.MAC) {
			plat = "Macintosh";
			os = "Intel Mac OS X 10_6_4";
		} else if (GlobalConfiguration.getCurrentOperatingSystem() != GlobalConfiguration.OperatingSystem.WINDOWS) {
			plat = "X11";
			os = "Linux i686";
		}
		StringBuilder buf = new StringBuilder(125);
		buf.append("Mozilla/5.0 (").append(plat).append("; U; ").append(os);
		buf.append("; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.44 Safari/534.7");
		return buf.toString();
	}

	public static URLConnection getURLConnection(final URL url, final String referer) throws IOException {
		final URLConnection con = url.openConnection();
		con.addRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
		con.addRequestProperty("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
		con.addRequestProperty("Accept-Encoding", "gzip,deflate");
		con.addRequestProperty("Accept-Language", "en-us,en;q=0.5");
		con.addRequestProperty("Connection", "keep-alive");
		con.addRequestProperty("Host", url.getHost());
		con.addRequestProperty("Keep-Alive", "300");
		if (referer != null) {
			con.addRequestProperty("Referer", referer);
		}
		con.addRequestProperty("User-Agent", getHttpUserAgent());
		return con;
	}

	public static int getVersion() {
		try {
			InputStream is = RUNNING_FROM_JAR ? GlobalConfiguration.class.getClassLoader().getResourceAsStream(Paths.Resources.VERSION) : new FileInputStream(Paths.VERSION);

			int off = 0;
			byte[] b = new byte[2];
			while ((off += is.read(b, off, 2 - off)) != 2) {
			}

			return ((0xFF & b[0]) << 8) + (0xFF & b[1]);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return -1;
	}
}
